from odoo import api, fields, models, _, Command
from odoo.exceptions import ValidationError


class SErpLock(models.Model):
    _name = 'sb.erp.lock'
    _inherit = ['portal.mixin', 'mail.thread.main.attachment', 'mail.activity.mixin']

    # ===============================================================================
    @api.depends('sb_workflow_id.state', 'sb_workflow_id')
    def _compute_approve_users(self):
        user_vals = []
        for item in self.sb_workflow_item_ids:
            for user in item.user_group_ids:
                user_vals.append((4, user.id))
        self.approve_users = user_vals

    def _compute_is_approve_user(self):
        self.ensure_one()
        is_approve_user = False
        if self.env.uid in self.approve_users.ids:
            for item in self.sb_workflow_item_ids:
                if item.state == 'approval' and self.env.uid in item.user_group_ids.ids:
                    is_approve_user = True
                    continue
        self.is_approve_user = is_approve_user

    @api.depends('sb_workflow_ids')
    def _compute_sb_workflow_ids_sum(self):
        for item in self:
            if item.sb_workflow_ids:
                item.sb_workflow_ids_sum = len(item.sb_workflow_ids)
            else:
                item.sb_workflow_ids_sum = 0

    approve_users = fields.Many2many('res.users', string='All Approve User', compute="_compute_approve_users",
                                     store=True)
    is_approve_user = fields.Boolean(default=False, compute='_compute_is_approve_user')
    is_approve_user_cancel = fields.Boolean(default=False)
    sb_workflow_template_id = fields.Many2one('sb.workflow.template', string="Approval Workflow Template",
                                              domain="[('sb_workflow_template_item_ids', '!=', False),"
                                                     "('workflow_type', '=', 'lock_erp')]")

    sb_workflow_id = fields.Many2one('sb.workflow', string="Current Approval Workflow", copy=False)
    sb_workflow_state = fields.Selection(related="sb_workflow_id.state", readonly=True, string="Approval Status",
                                         store=True)
    sb_workflow_item_ids = fields.One2many(related="sb_workflow_id.sb_workflow_item_ids", string="Approval Items")
    sb_workflow_attachments_ids = fields.One2many(related="sb_workflow_id.sb_workflow_attachments_ids",
                                                  string="Approval Attachments")
    sb_workflow_ids = fields.One2many('sb.workflow', 's_erp_lock_id', string="Approval Workflows")
    sb_workflow_ids_sum = fields.Integer(compute="_compute_sb_workflow_ids_sum", store=True)
    # ===============================================

    def _default_name(self):
        if self._context.get('default_is_unlock_apply', False):
            return self.env['ir.sequence'].next_by_code('sb.erp.unlock')
        else:
            return self.env['ir.sequence'].next_by_code('sb.erp.lock')

    name = fields.Char(string='Ref', default=_default_name)

    # ('lock_workorder', 'LocK Workorder'),
    # ('lock_delivery', 'Lock delivery')
    type = fields.Selection([('lock_order', 'Lock Order'),
                             ('lock_lot', 'Lock Lot')], string='Type')
    is_lock_order = fields.Boolean(default=False, string='Lock Order')
    is_lock_lot = fields.Boolean(default=False, string='Lock Lot')
    is_lock_workorder = fields.Boolean(default=False, string='Lock Workorder')
    is_lock_delivery = fields.Boolean(default=False, string='Lock Delivery')

    customer_ids = fields.Many2many('customer.item.code', 's_erp_lock_customer_code_rel',string='Customer Part')
    product_tmpl_ids = fields.Many2many('product.template', 's_erp_lock_product_template_rel', string='Product')
    sale_order_ids = fields.Many2many('sale.order', 's_erp_lock_sale_order_rel', string='MO')
    production_id = fields.Many2one('mrp.production', string='Production')
    production_ids = fields.Many2many('mrp.production')
    workorder_ids = fields.Many2many('mrp.workorder', string='Workorder')
    version = fields.Char(string='Version')
    note = fields.Char()
    # ==========解锁申请=========
    is_unlock_apply = fields.Boolean(default=False)
    parent_id = fields.Many2one('sb.erp.lock', string='Lock Apply')

    @api.onchange('parent_id', 'is_unlock_apply')
    def onchange_sb_fields(self):
        if self.parent_id and self.is_unlock_apply:
            self.update({
                'is_lock_order': self.parent_id.is_lock_order,
                'is_lock_lot': self.parent_id.is_lock_lot,
                'is_lock_workorder': self.parent_id.is_lock_workorder,
                'is_lock_delivery': self.parent_id.is_lock_delivery,
                'customer_ids': [(4, c.id) for c in self.parent_id.customer_ids],
                'product_tmpl_ids': [(4, c.id) for c in self.parent_id.product_tmpl_ids],
                'sale_order_ids': [(4, c.id) for c in self.parent_id.sale_order_ids],
                'workorder_ids': [(4, c.id) for c in self.parent_id.workorder_ids],
                'production_id': self.parent_id.production_id.id,
            })

    @api.onchange('sale_order_ids')
    def onchange_production_ids(self):
        s_mrp_production_ids = self.sale_order_ids.mapped('order_line').mapped('s_mrp_production_ids')
        if s_mrp_production_ids:
            self.production_ids = [(4, p.id) for p in s_mrp_production_ids]
        else:
            self.production_ids = [Command.clear()]

    def create_workflow(self):
        # if self.sale_order_id.sb_workflow_state == 'approval' and self.apply_type in ['change_status', 'change_design']:
        #     raise ValidationError(_('Unapproved MO cannot be Change'))
        if all([not self.is_lock_order,not self.is_lock_lot,not self.is_lock_workorder,not self.is_lock_delivery]):
            raise ValidationError(_('请选择锁单类型'))
        if self.sb_workflow_template_id:
            if len(self.sb_workflow_ids) > 0:
                workflow_sum = len(self.sb_workflow_ids) + 1
            else:
                workflow_sum = 1
            if not self.sb_workflow_template_id.sb_workflow_template_item_ids:
                raise ValidationError(_('Please configure the approver first！'))
            # 创建审批流
            new_wf_id = self.env['sb.workflow'].sudo().create({
                'name': self.name + '- Approval Flow' + '-' + str(workflow_sum),
                'approval_time': fields.Datetime.now(),
                'workflow_type': 'lock_erp',
                's_erp_lock_id': self.id,
            })
            self.sb_workflow_id = new_wf_id.id
            # 根据模板生成审批项
            item_audit_levels = []
            for item in self.sb_workflow_template_id.sb_workflow_template_item_ids:
                new_item = self.env['sb.workflow.item'].sudo().create({
                    'name': item.name,
                    'user_group_ids': item.user_group_ids.ids,
                    'audit_level': item.audit_level,
                    'sb_workflow_id': new_wf_id.id,
                    'state': 'wait_forward'
                })
                # 收集生成的审核项的所有层级
                item_audit_levels.append(new_item.audit_level)
            # 去重排序
            item_audit_levels = list(set(item_audit_levels))
            item_audit_levels.sort()
            # 开放最低层级的神匹配
            for n_item in new_wf_id.sb_workflow_item_ids:
                if n_item.audit_level == item_audit_levels[0]:
                    n_item.state = 'approval'
            # self._update_product_template()
            self._erp_lock()
        else:
            raise ValidationError(_('Please select an approval template.'))

    def _erp_lock(self):
        if self.is_lock_order:
            # 锁下单
            if self.customer_ids and not self.product_tmpl_ids:
                for customer in self.customer_ids:
                    for product in customer.product_tmpl_ids:
                        product.s_disable_order = True
            elif self.product_tmpl_ids:
                for product in self.product_tmpl_ids:
                    product.s_disable_order = True

        if self.is_lock_lot:
            # 锁下卡
            if self.product_tmpl_ids and not self.sale_order_ids:
                for product in self.product_tmpl_ids:
                    product.s_disable_down_card = True
            elif self.sale_order_ids:
                for sale in self.sale_order_ids:
                    sale.is_lock = True
            elif self.customer_ids and not self.product_tmpl_ids:
                for customer in self.customer_ids:
                    for product in customer.product_tmpl_ids:
                        product.s_disable_down_card = True

        if self.is_lock_workorder:
            # 漏斗, 锁过数
            if self.workorder_ids:
                self.workorder_ids.write({'is_lock': True})
            elif self.production_id:
                mrp_prods = self.production_id
                mrp_prods |= self._get_child_mrp(self.production_id)
                mrp_prods.write({'is_lock': True})
            elif self.sale_order_ids:
                self.sale_order_ids.write({'is_lock': True})
                # self.sale_order_ids.order_line.mapped('s_mrp_production_ids').write({'is_lock': True})
                s_mrp_production_ids = self.sale_order_ids.order_line.mapped('s_mrp_production_ids')
                mrp_prods = s_mrp_production_ids
                for mrp in s_mrp_production_ids:
                    mrp_prods |= self._get_parent_mrp(mrp)
                    mrp_prods |= self._get_child_mrp(mrp)
                # 锁定工单
                for mrp in mrp_prods:
                    mrp.filtered(lambda x: x.state != 'done').is_lock = True
                    mrp.filtered(lambda x: x.state != 'done').lock_reason = self.note
                # self.sale_order_ids.order_line.mapped('s_mrp_production_ids').mapped('workorder_ids').write({'is_lock': True})
            elif self.product_tmpl_ids:
                self.product_tmpl_ids.write({'s_disable_workorder': True})

        if self.is_lock_delivery:
            if self.production_id:
                self.production_id.write({'s_disable_delivery': True})
            elif self.sale_order_ids:
                self.sale_order_ids.write({'s_disable_delivery': True})
            elif self.product_tmpl_ids:
                self.product_tmpl_ids.write({'s_disable_delivery': True})

    def _get_child_mrp(self, mrp):
        child_ids = mrp._get_children()
        # 欠单
        mrp_backorders = mrp.procurement_group_id.mrp_production_ids
        return child_ids | mrp_backorders

    def _get_parent_mrp(self, mrp):
        parent_ids = mrp._get_sources()
        # 欠单
        mrp_backorders = mrp.procurement_group_id.mrp_production_ids
        return parent_ids | mrp_backorders | mrp

    def _update_product_template(self):
        if self.customer_ids and not self.product_tmpl_ids:
            for customer in self.customer_ids:
                for product in customer.product_tmpl_ids:
                    if self.type == 'lock_order':
                        product.s_disable_order = True
                    elif self.type == 'lock_lot':
                        product.s_disable_down_card = True
        elif self.product_tmpl_ids:
            for product in self.product_tmpl_ids:
                if self.type == 'lock_order':
                    product.s_disable_order = True
                elif self.type == 'lock_lot':
                    product.s_disable_down_card = True

